<template>
  <div>
    <div class="uploadButton">
      <input id="upload" ref="file" type="file" style="display: none" @change="uploadFile()">
      <el-button type="primary" @click="goFile">上传<i class="el-icon-upload el-icon--right"/></el-button>
    </div>
    <!--  提示  -->
    <div class="uploadInfo">
      <el-row v-if="statusShow" type="flex">
        <span style="font-size: 8px;padding: 0 60px 0 10px;">{{ fileInfo.fileName }}</span>
        <el-progress class="progress-1" :percentage="schedule" :stroke-width="4" style="width: 200px;"/>
        <span v-show="schedule === 100" style="font-size: 8px;padding: 0 10px 0 20px;color: #31cd31;">上传成功!</span>
      </el-row>
    </div>
  </div>
</template>

<script>
import {reactive, getCurrentInstance, ref} from 'vue'
import SparkMD5 from 'spark-md5'
import {ElMessage} from "element-plus";

export default {
  name: "upload",
  setup() {
    const fileInfo = reactive({
      fileName: '',
      fileMd5: '',
      chunkCount: 0
    })
    const {proxy} = getCurrentInstance();
    const statusShow = ref(false)
    const schedule = ref(0)
    // 分片大小 5mb
    const chunkSize = ref(5 * 1024 * 1024)
    // 按钮跳转
    const goFile = () => {
      proxy.$refs.file.click()
    }

    const uploadFile = async () => {
      // 获取用户选择的文件
      const file = document.getElementById('upload').files[0]

      if (file === undefined) {
        ElMessage.error('文件损坏请重新上传')
        return
      }

      if (file.size > 0) {
        statusShow.value = true
        fileInfo.fileName = file.name
        fileInfo.chunkCount = Math.ceil(file.size / chunkSize.value)
        fileInfo.fileMd5 = await getFileMd5(file)
      }
      console.log(fileInfo)

      proxy.$http.post('/api/chunk', fileInfo).then(
          async res => {
            // 分片上传完成 待合并文件
            if (res.data.data.uploadCode === 3) {
              composeFile(fileInfo)
              return
            }

            if (res.data.data.uploadCode === 1) {
              schedule.value = 100
              ElMessage.success('秒传，文件地址是：' + res.data.data.fileUrl)
              return
            }

            const chunkUploadUrls = res.data.data.chunkUploadUrls

            for (const item of chunkUploadUrls) {
              // 分片开始位置
              const start = (item.partNumber - 1) * chunkSize.value
              // 分片结束位置
              const end = Math.min(file.size, start + chunkSize.value)
              // 取文件指定范围内的byte，从而得到分片数据
              const chunkFile = file.slice(start, end)
              await proxy.$http.put(item.uploadUrl, chunkFile)
              schedule.value = parseFloat((item.partNumber / fileInfo.chunkCount * 100).toString().substring(0, 4))
            }
            composeFile(fileInfo)
          }
      )
    }

    const getFileMd5 = (file) => {
      const fileReader = new FileReader()
      fileReader.readAsBinaryString(file)
      const spark = new SparkMD5()
      return new Promise((resolve) => {
        fileReader.onload = (e) => {
          spark.appendBinary(e.target.result)
          resolve(spark.end())
        }
      })
    }

    const composeFile = (fileInfo) => {
      proxy.$http.post('/api/compose', fileInfo).then(
          res => {
            if (res.data.code === 0) ElMessage.success('上传成功，文件地址是：' + res.data.data.fileUrl)
          }
      )
    }

    return {
      fileInfo,
      schedule,
      statusShow,
      chunkSize,

      goFile,
      uploadFile
    }
  }
}
</script>

<style scoped>

</style>